package com.app.h5.pic;

import android.content.Context;
import android.content.res.TypedArray;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

import com.app.h5.R;

import androidx.appcompat.widget.AppCompatImageView;

/*app:sizeRatio="2:1"*/

/**
 * 等同约束布局的高宽比属性
 * <p>
 *
 * @author: Android dave
 * github : https://github.com/getActivity/AndroidProject
 * time   : 2019/08/23
 * desc   : 按照比例显示的 RoundedImageView
 */
public final class RatioImageView extends AppCompatImageView {

    /**
     * 宽高比例
     */
    private float mWidthRatio;
    private float mHeightRatio;

    public RatioImageView(Context context) {
        this(context, null);
    }

    public RatioImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RatioImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        final TypedArray array = context.obtainStyledAttributes(attrs, com.app.h5.R.styleable.RatioImageView);
        String sizeRatio = array.getString(R.styleable.RatioImageView_sizeRatio);
        if (!TextUtils.isEmpty(sizeRatio)) {
            String[] arrays = sizeRatio.split(":");
            switch (arrays.length) {
                case 1:
                    mWidthRatio = Float.parseFloat(arrays[0]);
                    mHeightRatio = 1;
                    break;
                case 2:
                    mWidthRatio = Float.parseFloat(arrays[0]);
                    mHeightRatio = Float.parseFloat(arrays[1]);
                    break;
                default:
                    throw new IllegalArgumentException("are you ok?");
            }
        }
        array.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mWidthRatio != 0 && mHeightRatio != 0) {

            float sizeRatio = getSizeRatio();

            ViewGroup.LayoutParams layoutParams = getLayoutParams();

            int widthSpecMode = View.MeasureSpec.getMode(widthMeasureSpec);
            int widthSpecSize = View.MeasureSpec.getSize(widthMeasureSpec);

            int heightSpecMode = View.MeasureSpec.getMode(heightMeasureSpec);
            int heightSpecSize = View.MeasureSpec.getSize(heightMeasureSpec);

            // 一般情况下 LayoutParams.WRAP_CONTENT 对应着 MeasureSpec.AT_MOST（自适应），但是由于我们在代码中强制修改了测量模式为 MeasureSpec.EXACTLY（固定值）
            // 这样会有可能重新触发一次 onMeasure 方法，这个时候传入测量模式的就不是 MeasureSpec.AT_MOST（自适应） 模式，而是 MeasureSpec.EXACTLY（固定值）模式
            // 所以我们要进行双重判断，首先判断 LayoutParams，再判断测量模式，这样就能避免因为修改了测量模式触发对宽高的重新计算，最终导致计算结果和上次计算的不同
            if (layoutParams.width != ViewGroup.LayoutParams.WRAP_CONTENT && layoutParams.height != ViewGroup.LayoutParams.WRAP_CONTENT
                    && widthSpecMode == View.MeasureSpec.EXACTLY && heightSpecMode == View.MeasureSpec.EXACTLY) {
                // 如果当前宽度和高度都是写死的
                if (widthSpecSize != 0 && heightSpecSize == 0) {
                    //高度为0,直接当做权重
                    heightMeasureSpec = View.MeasureSpec.makeMeasureSpec((int) (widthSpecSize / sizeRatio), View.MeasureSpec.EXACTLY);
                } else if (widthSpecSize / sizeRatio <= heightSpecSize) {
                    // 如果宽度经过比例换算不超过原有的高度
                    heightMeasureSpec = View.MeasureSpec.makeMeasureSpec((int) (widthSpecSize / sizeRatio), View.MeasureSpec.EXACTLY);
                } else if (heightSpecSize * sizeRatio <= widthSpecSize) {
                    // 如果高度经过比例换算不超过原有的宽度
                    widthMeasureSpec = View.MeasureSpec.makeMeasureSpec((int) (heightSpecSize * sizeRatio), View.MeasureSpec.EXACTLY);
                }
            } else if (layoutParams.width != ViewGroup.LayoutParams.WRAP_CONTENT && widthSpecMode == View.MeasureSpec.EXACTLY && heightSpecMode != View.MeasureSpec.EXACTLY) {
                // 如果当前宽度是写死的，但是高度不写死
                heightMeasureSpec = View.MeasureSpec.makeMeasureSpec((int) (widthSpecSize / sizeRatio), View.MeasureSpec.EXACTLY);
            } else if (layoutParams.height != ViewGroup.LayoutParams.WRAP_CONTENT && heightSpecMode == View.MeasureSpec.EXACTLY && widthSpecMode != View.MeasureSpec.EXACTLY) {
                // 如果当前高度是写死的，但是宽度不写死
                widthMeasureSpec = View.MeasureSpec.makeMeasureSpec((int) (heightSpecSize * sizeRatio), View.MeasureSpec.EXACTLY);
            }
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }


    public float getWidthRatio() {
        return mWidthRatio;
    }

    public float getHeightRatio() {
        return mHeightRatio;
    }

    /**
     * 获取宽高比
     */
    public float getSizeRatio() {
        return mWidthRatio / mHeightRatio;
    }

    /**
     * 设置宽高比
     */
    public void setSizeRatio(float widthRatio, float heightRatio) {
        mWidthRatio = widthRatio;
        mHeightRatio = heightRatio;
        requestLayout();
        invalidate();
    }
}